/******/
(function (modules) { // webpackBootstrap
    /******/ 	// The module cache
    /******/
    var installedModules = {};

    /******/ 	// The require function
    /******/
    function __webpack_require__(moduleId) {

        /******/ 		// Check if module is in cache
        /******/
        if (installedModules[moduleId])
        /******/            return installedModules[moduleId].exports;

        /******/ 		// Create a new module (and put it into the cache)
        /******/
        var module = installedModules[moduleId] = {
            /******/            exports: {},
            /******/            id: moduleId,
            /******/            loaded: false
            /******/
        };

        /******/ 		// Execute the module function
        /******/
        modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

        /******/ 		// Flag the module as loaded
        /******/
        module.loaded = true;

        /******/ 		// Return the exports of the module
        /******/
        return module.exports;
        /******/
    }


    /******/ 	// expose the modules object (__webpack_modules__)
    /******/
    __webpack_require__.m = modules;

    /******/ 	// expose the module cache
    /******/
    __webpack_require__.c = installedModules;

    /******/ 	// __webpack_public_path__
    /******/
    __webpack_require__.p = "";

    /******/ 	// Load entry module and return exports
    /******/
    return __webpack_require__(0);
    /******/
})
/************************************************************************/
/******/([
    /* 0 */
    /***/ function (module, exports, __webpack_require__) {

        'use strict';

        var _push_service_worker = __webpack_require__(1);

        var _push_service_worker2 = _interopRequireDefault(_push_service_worker);

        function _interopRequireDefault(obj) {
            return obj && obj.__esModule ? obj : {default: obj};
        }

        _push_service_worker2.default.initialize(); // no_unit_test

        /***/
    },
    /* 1 */
    /***/ function (module, exports, __webpack_require__) {

        'use strict';

        Object.defineProperty(exports, "__esModule", {
            value: true
        });

        var _utils = __webpack_require__(2);

        var _utils2 = _interopRequireDefault(_utils);

        var _client_filters = __webpack_require__(3);

        var _client_filters2 = _interopRequireDefault(_client_filters);

        var _notification_click_handlers = __webpack_require__(4);

        var _notification_click_handlers2 = _interopRequireDefault(_notification_click_handlers);

        var _notification_display_handlers = __webpack_require__(5);

        var _notification_display_handlers2 = _interopRequireDefault(_notification_display_handlers);

        var _scribe = __webpack_require__(6);

        var _scribe2 = _interopRequireDefault(_scribe);

        var _indexed_db = __webpack_require__(7);

        var _indexed_db2 = _interopRequireDefault(_indexed_db);

        function _interopRequireDefault(obj) {
            return obj && obj.__esModule ? obj : {default: obj};
        }

        /*
         * To bundle service worker file, run `npm run build:service-worker` in `web-resources` directory
         */

        var NOTIFICATIONS_ENDPOINT = '/i/push_notifications';
        var WORKER_API_VERSION = 1;

        function PushServiceWorker() {
            var _this = this;

            this.scribe = _scribe2.default;
            this.scribeActionForData = function (action) {
                var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

                _this.scribe({
                    element: data.scribe_target || 'other',
                    action: action
                }, {
                    impression_id: data.impression_id
                });
            };

            /*
             *
             * Logic for fetching the JSON notifications from the endpoint
             * dealing with the response and displaying the notifications
             *
             */
            this.displayNotifications = function (notifications) {
                var _this2 = this;

                if (!notifications) {
                    return Promise.resolve();
                }
                return Promise.all(notifications.map(function (notification) {
                    _this2.scribeActionForData('impression', notification.data);

                    // Chrome requires that a notification be shown before the push event is completed
                    // unless theres's a visible client window so we only delegate display handling in that case
                    return _utils2.default.getClients([_client_filters2.default.visible]).then(function (clientList) {
                        var visibleClient = clientList[0];
                        // Newer push uses data.type instead
                        var notificationType = notification.data.type;
                        var displayHandler = visibleClient && _notification_display_handlers2.default[notificationType] || _notification_display_handlers2.default['default'];
                        return displayHandler(notification, visibleClient);
                    });
                }));
            };

            this.fetchNotifications = function (cursors, impressionId) {
                var _this3 = this;

                var params = ['apiv=' + WORKER_API_VERSION, cursors.dm && 'dm_cursor=' + encodeURIComponent(cursors.dm), cursors.interactions && 'min_position=' + encodeURIComponent(cursors.interactions)].filter(function (param) {
                    return !!param;
                });

                return self.fetch(NOTIFICATIONS_ENDPOINT + '?' + params.join('&'), {credentials: 'include'}).then(function (response) {
                    return response.json();
                }).then(function (data) {
                    return data.error || !data.notifications ? Promise.reject('Invalid API response') : data;
                }).then(function (data) {
                    return _this3.storeCursorsFromResponse(data);
                }).then(function (data) {
                    data.notifications.forEach(function (notification) {
                        notification.data.uri = notification.data.url;
                        notification.data.type = notification.data.notificationType;
                        notification.data.scribe_target = notification.data.scribeElementName;
                        notification.data.impression_id = impressionId;
                    });
                    return data.notifications;
                }).catch(function (err) {
                    return (// Unable to fetch data for some reason, most likely they are logged out
                        _this3.scribe({action: 'fetch_failure'}, {impression_id: impressionId, message: err.message})
                    );
                });
            };

            this.pushHandler = function (pushEvent) {
                var _this4 = this;

                if (pushEvent.data) {
                    pushEvent.waitUntil(this.displayNotifications([pushEvent.data.json()]));
                } else {
                    var impressionId = _utils2.default.generatePushId();
                    this.scribe({
                        action: 'received'
                    }, {
                        impression_id: impressionId
                    });

                    pushEvent.waitUntil(this.openIndexedDB('notification_cursors').then(function (db) {
                        return _this4.getCursors(db);
                    }).then(function (cursors) {
                        return _this4.fetchNotifications(cursors, impressionId);
                    }).then(function (notifications) {
                        return _this4.displayNotifications(notifications);
                    }));
                }
            };

            this.notificationcloseHandler = function (event) {
                var data = event.notification.data;
                this.scribeActionForData('dismiss', data);
            };

            this.notificationclickHandler = function (event) {
                event.notification.close();

                var data = event.notification.data;
                this.scribeActionForData('open', data);

                var clickHandler = _notification_click_handlers2.default[data.type] || _notification_click_handlers2.default['default'];
                event.waitUntil(clickHandler(data));
            };

            /*
             * Indexed DB Interface
             */
            this.openIndexedDB = function (name) {
                return _indexed_db2.default.open('notification_cursors', 2, [{name: 'cursors', keyPath: 'name'}]);
            };

            this.getCursors = function (db) {
                return db.getAll('cursors').then(function (cursors) {
                    var result = cursors.reduce(function (acc, val) {
                        acc[val.name] = val.cursor;
                        return acc;
                    }, {});
                    return result;
                });
            };

            this.storeCursorsFromResponse = function (data) {
                return this.openIndexedDB('notification_cursors').then(function (db) {
                    if (data.dmCursor) {
                        db.put({cursors: [{name: 'dm', cursor: data.dmCursor}]});
                    }
                    if (data.interactionsCursor) {
                        db.put({cursors: [{name: 'interactions', cursor: data.interactionsCursor}]});
                    }
                    return data;
                });
            };

            /*
             * Service worker interface
             */
            this.initialize = function () {
                self.addEventListener('push', this.pushHandler.bind(this));

                self.addEventListener('notificationclose', this.notificationcloseHandler.bind(this));

                self.addEventListener('notificationclick', this.notificationclickHandler.bind(this));

                // Make this worker active as soon as it's fetched instead of waiting for page close like normal
                self.addEventListener('install', function (event) {
                    return event.waitUntil(self.skipWaiting());
                });
                self.addEventListener('activate', function (event) {
                    return event.waitUntil(self.clients.claim());
                });
            };
        }

        exports.default = new PushServiceWorker();

        /***/
    },
    /* 2 */
    /***/ function (module, exports, __webpack_require__) {

        'use strict';

        Object.defineProperty(exports, "__esModule", {
            value: true
        });

        var _client_filters = __webpack_require__(3);

        var _client_filters2 = _interopRequireDefault(_client_filters);

        function _interopRequireDefault(obj) {
            return obj && obj.__esModule ? obj : {default: obj};
        }

        /* Service Worker utils */
        exports.default = {
            displayNotification: function displayNotification(notification) {
                return self.registration.showNotification(notification.title, notification);
            },

            getDate: Date.now,

            generatePushId: function generatePushId() {
                return parseInt(Math.random() * Number.MAX_SAFE_INTEGER, 10);
            },

            combineFilters: function combineFilters(filters) {
                return function (item) {
                    return filters.every(function (filter) {
                        return filter(item);
                    });
                };
            },

            getClients: function getClients(filters) {
                filters = filters || [];
                filters.push(_client_filters2.default.topLevel);
                var combinedFilter = this.combineFilters(filters);
                return self.clients.matchAll({type: 'window'}).then(function (clientList) {
                    return clientList.filter(combinedFilter);
                });
            },

            triggerOnClient: function triggerOnClient(client, eventName, eventData) {
                return client.postMessage(JSON.stringify({
                    event: eventName,
                    data: eventData
                }));
            },

            openURL: function openURL(url, client) {
                url = url || '/';
                if (client && client.navigate) {
                    client.focus && client.focus();
                    return client.navigate(url);
                } else if (self.clients.openWindow) {
                    return self.clients.openWindow(url);
                } else {
                    return Promise.reject('Opening a URL via service worker is not supported in this browser');
                }
            }
        };

        /***/
    },
    /* 3 */
    /***/ function (module, exports) {

        'use strict';

        Object.defineProperty(exports, "__esModule", {
            value: true
        });
        // no_unit_test
        exports.default = {
            visible: function visible(client) {
                return client.visibilityState === 'visible';
            },
            topLevel: function topLevel(client) {
                return client.frameType === 'top-level';
            },
            focused: function focused(client) {
                return client.focused;
            },
            urlEndsWith: function urlEndsWith(endsWith) {
                return function (client) {
                    return client.url.endsWith(endsWith);
                };
            }
        };

        /***/
    },
    /* 4 */
    /***/ function (module, exports, __webpack_require__) {

        'use strict';

        Object.defineProperty(exports, "__esModule", {
            value: true
        });

        var _client_filters = __webpack_require__(3);

        var _client_filters2 = _interopRequireDefault(_client_filters);

        var _utils = __webpack_require__(2);

        var _utils2 = _interopRequireDefault(_utils);

        function _interopRequireDefault(obj) {
            return obj && obj.__esModule ? obj : {default: obj};
        }

        // Focus and trigger an event on client if available
        // Otherwise, open the URL provided by the notification
        var dmNotificationClickHandler = function dmNotificationClickHandler(data) {
            return _utils2.default.getClients().then(function (clientList) {
                var activeClient = clientList[0];
                if (activeClient && activeClient.focus) {
                    activeClient.focus();
                    _utils2.default.triggerOnClient(activeClient, 'uiDMNotificationClicked', data.notificationData);
                    return Promise.resolve();
                } else {
                    return _utils2.default.openURL(data.uri || '/');
                }
            });
        };

        var defaultNotificationClickHandler = function defaultNotificationClickHandler(data) {
            var endsWithFilter = _client_filters2.default.urlEndsWith(data.uri);
            return _utils2.default.getClients([endsWithFilter]).then(function (clientList) {
                var client = clientList[0];
                return Promise.resolve(client && client.focus ? client.focus() : _utils2.default.openURL(data.uri));
            });
        };

        var notificationClickHandlers = {
            'dm': dmNotificationClickHandler,
            'default': defaultNotificationClickHandler
        };

        exports.default = notificationClickHandlers;

        /***/
    },
    /* 5 */
    /***/ function (module, exports, __webpack_require__) {

        'use strict';

        Object.defineProperty(exports, "__esModule", {
            value: true
        });

        var _utils = __webpack_require__(2);

        var _utils2 = _interopRequireDefault(_utils);

        function _interopRequireDefault(obj) {
            return obj && obj.__esModule ? obj : {default: obj};
        }

        var dmNotificationDisplayHandler = function dmNotificationDisplayHandler(notification, visibleClient) {
            _utils2.default.triggerOnClient(visibleClient, 'dataDMPushReceived', notification.data.notificationData);
        };

        var dmIbisNotificationDisplayHandler = function dmIbisNotificationDisplayHandler(notification, visibleClient) {
            // convo_id comes from the tag which is {{model}}-{{convo_id}}
            var parts = notification.tag.split('-');
            var conversationId = parts[parts.length - 1];
            return _utils2.default.triggerOnClient(visibleClient, 'dataDMPushReceived', {
                // Ibis does not send message id, so the id field is missing here. Would be more accurate if included
                conversation_id: conversationId,
                title: notification.title,
                body: notification.body,
                icon: notification.icon
            });
        };

        // Suppress error notification if there's a visible client
        var errorNotificationHandler = function errorNotificationHandler() {
            return;
        };

        var notificationDisplayHandlers = {
            'dm': dmNotificationDisplayHandler,
            'message': dmIbisNotificationDisplayHandler,
            'group_message': dmIbisNotificationDisplayHandler,
            'error': errorNotificationHandler,
            'default': _utils2.default.displayNotification
        };

        exports.default = notificationDisplayHandlers;

        /***/
    },
    /* 6 */
    /***/ function (module, exports, __webpack_require__) {

        'use strict';

        Object.defineProperty(exports, "__esModule", {
            value: true
        });

        var _utils = __webpack_require__(2);

        var _utils2 = _interopRequireDefault(_utils);

        function _interopRequireDefault(obj) {
            return obj && obj.__esModule ? obj : {default: obj};
        }

        var CLIENT_APP_ID = 268278;

        /*
         * Lightweight scribe interface for logging display and clicks
         */
        // no_unit_test
        var scribe = function scribe(terms, data) {
            data = data || {};

            if (!terms || !terms.action) {
                throw new Error('You must specify an action term in your client_event.');
            }

            // http://go/clienteventnamespace for details
            var eventNamespace = {
                client: 'web',
                page: 'service_worker',
                section: terms.section || '',
                component: terms.component || '',
                element: terms.element || '',
                action: terms.action
            };

            var json = Object.assign({}, data, {
                event_namespace: eventNamespace,
                _category_: 'client_event',
                triggered_on: _utils2.default.getDate(),
                format_version: 2,
                client_app_id: CLIENT_APP_ID // Desktop Web
            });

            self.fetch('/i/jot', {
                credentials: 'include',
                method: 'post',
                headers: {
                    'Accept': 'application/x-www-form-urlencoded',
                    'Content-Type': 'application/x-www-form-urlencoded'
                },
                body: 'log=' + encodeURIComponent(JSON.stringify(json))
            });
        };

        exports.default = scribe;

        /***/
    },
    /* 7 */
    /***/ function (module, exports, __webpack_require__) {

        'use strict';

        Object.defineProperty(exports, "__esModule", {
            value: true
        });

        var _promise_logger = __webpack_require__(8);

        var _promise_logger2 = _interopRequireDefault(_promise_logger);

        function _interopRequireDefault(obj) {
            return obj && obj.__esModule ? obj : {default: obj};
        }

        // Use self instead of window for supporting worker contexts
        var IndexedDB = self.indexedDB || self.mozIndexedDB || self.webkitIndexedDB || self.msIndexedDB;
        var KeyRange = self.IDBKeyRange || self.webkitIDBKeyRange || self.msIDBKeyRange;
        var Transaction = {
            readwrite: (self.IDBTransaction || self.webkitIDBTransaction || self.msIDBTransaction || {}).READ_WRITE || 'readwrite',
            readonly: (self.IDBTransaction || self.webkitIDBTransaction || self.msIDBTransaction || {}).READ_ONLY || 'readonly'
        };

        exports.default = IndexedDBClient;


        function IndexedDBClient() {
            var args = Array.prototype.slice.call(arguments);
            if (this instanceof IndexedDBClient) {
                var database = args[0];
                this.database = database;
                this.name = database.name;
                this.version = database.version;
                this.stores = getObjectStoreNames(database);

                database.onversionchange = function () {
                    database.close();
                    self.location && self.location.reload(true);
                };
            } else {
                return IndexedDBClient.open.apply(null, args);
            }
        }

        /*****************************
         _____ __        __  _
         / ___// /_____ _/ /_(_)____
         \__ \/ __/ __ `/ __/ / ___/
         ___/ / /_/ /_/ / /_/ / /__
         /____/\__/\__,_/\__/_/\___/

         *****************************/

        IndexedDBClient.KeyRange = KeyRange;

        IndexedDBClient.deleteDatabase = function (name) {
            return new Promise(function (resolve) {
                var request = IndexedDB.deleteDatabase(name);
                request.onsuccess = request.onerror = resolve;
            });
        };

        IndexedDBClient.isSupported = function () {
            return !!IndexedDB;
        };

        IndexedDBClient.open = function (name, version, schema, isIncrementalSchemaUpdate) {
            var loggingOptions = {
                title: 'IndexedDB "' + name + '" version ' + version,
                enabled: self.DEBUG && self.DEBUG.enabled
            };

            // Log resolve or failure of open when debug is enabled
            return (0, _promise_logger2.default)(loggingOptions, new Promise(function (openResolve, openReject) {
                if (!IndexedDBClient.isSupported()) {
                    return openReject('not supported');
                }

                var request = version ? IndexedDB.open(name, version) : IndexedDB.open(name);
                var migration = void 0;

                request.onupgradeneeded = function (e) {
                    var database = e.target.result;
                    var migrationLoggingOptions = {
                        title: 'IndexedDB "' + name + '" migration from version ' + e.oldVersion + ' to ' + e.newVersion,
                        enabled: self.DEBUG && self.DEBUG.enabled
                    };

                    // Log resolve, progress and failure of the migration when debug is enabled
                    (0, _promise_logger2.default)(migrationLoggingOptions, new Promise(function (migrationResolve, migrationReject) {
                        if (!isIncrementalSchemaUpdate) {
                            // Delete previous schema
                            getObjectStoreNames(database).forEach(function (store) {
                                return database.deleteObjectStore(store);
                            });
                        }

                        // Create new schema
                        var existingObjectStores = getObjectStoreNames(database);
                        var promises = (schema || []).map(function (config) {
                            return new Promise(function (resolve, reject) {
                                var name = config.name;
                                var keyPath = config.keyPath;
                                var indexes = config.indexes || [];

                                if (existingObjectStores.indexOf(name) < 0) {
                                    var store = database.createObjectStore(name, {keyPath: keyPath});
                                    indexes.forEach(function (index) {
                                        return store.createIndex(index.name, index.keyPath, index);
                                    });
                                    return store;
                                }
                            });
                        });

                        return Promise.all(promises).then(migrationResolve, migrationReject);
                    }));
                };

                request.onsuccess = function (e) {
                    (migration || Promise.resolve()).then(function () {
                        var database = new IndexedDBClient(e.target.result);
                        return openResolve(database);
                    }).catch(openReject);
                };

                request.onblocked = function (e) {
                    openReject('open blocked', e.target.error);
                };
                request.onerror = function (e) {
                    openReject('open error', e.target.error);
                    return true; // Prevents `InvalidStateError` and `UnknownError` exceptions.
                };
            }));
        };

        /********************************************
         ____           __
         /  _/___  _____/ /_____ _____  ________
         / // __ \/ ___/ __/ __ `/ __ \/ ___/ _ \
         _/ // / / (__  ) /_/ /_/ / / / / /__/  __/
         /___/_/ /_/____/\__/\__,_/_/ /_/\___/\___/

         ********************************************/

        /**
         * This is an insert only function. See #put for an update or insert function.
         */
        IndexedDBClient.prototype.add = function (data) {
            return this.insert('add', data);
        };

        IndexedDBClient.prototype.clear = function () {
            var stores = arguments.length ? Array.prototype.slice.call(arguments) : this.stores;

            // Using multiple transactions due to Safari bug: https://bugs.webkit.org/show_bug.cgi?id=136937
            var promises = stores.map(function (store) {
                return this.transaction(store, Transaction.readwrite, function (transaction) {
                    return transaction.objectStore(store).clear();
                });
            }, this);

            return Promise.all(promises);
        };

        IndexedDBClient.prototype.close = function () {
            var _this = this;

            return new Promise(function (resolve) {
                _this.database.close();
                return resolve();
            });
        };

        /**
         * This function naming deviates slightly from the IndexedDB specification because
         * `delete` is a JS keyword that can cause issues in pre-ES5 browsers.
         */
        IndexedDBClient.prototype.destroy = function (store, key) {
            return this.transaction(store, Transaction.readwrite, function (transaction) {
                return (// Using bracket notation to appease pre-ES5 browsers.
                    transaction.objectStore(store)['delete'](key)
                );
            });
        };

        IndexedDBClient.prototype.get = function (store, key) {
            return this.transaction(store, Transaction.readonly, function (transaction) {
                return transaction.objectStore(store).get(key);
            }).then(function (e) {
                return e.target.result;
            });
        };

        IndexedDBClient.prototype.getAll = function () /* store, [index], [keyRange] */ {
            var args = Array.prototype.slice.call(arguments).filter(function (item) {
                return item != null;
            });

            var len = args.length;
            var store = args[0];
            var index = typeof args[1] === 'string' ? args[1] : null;
            var keyRange = typeof args[len - 1] !== 'string' ? args[len - 1] : null;
            var db = this.database;

            return new Promise(function (resolve, reject) {
                var transaction = db.transaction(store, Transaction.readonly);
                var source = index ? transaction.objectStore(store).index(index) : transaction.objectStore(store);

                var items = [];
                var request = source.openCursor(keyRange);
                request.onerror = reject;
                request.onsuccess = function (e) {
                    var cursor = e.target.result;
                    if (cursor) {
                        items.push(cursor.value);
                        cursor['continue'](); // Using bracket notation to appease pre-ES5 browsers.
                    } else {
                        resolve(items);
                    }
                };
            });
        };

        IndexedDBClient.prototype.getByPrefix = function () /* store, [index], prefix */ {
            var args = Array.prototype.slice.call(arguments).filter(function (item) {
                return item != null;
            });

            var store = args[0];
            var index = args.length === 3 ? args[1] : null;
            var prefix = args[args.length - 1];

            return this.getAll(store, index, KeyRange.bound(prefix, prefix + '\uFFFF', false, false));
        };

        /**
         * This is an update or insert function. See #add for an insert only function.
         */
        IndexedDBClient.prototype.put = function (data) {
            return this.insert('put', data);
        };

        /************************************
         ____       _             __
         / __ \_____(_)   ______ _/ /____
         / /_/ / ___/ / | / / __ `/ __/ _ \
         / ____/ /  / /| |/ / /_/ / /_/  __/
         /_/   /_/  /_/ |___/\__,_/\__/\___/

         ************************************/

        IndexedDBClient.prototype.insert = function (method, data) {
            var stores = Object.keys(data);

            // Using multiple transactions due to Safari bug: https://bugs.webkit.org/show_bug.cgi?id=136937
            var promises = stores.map(function (store) {
                return this.transaction(store, Transaction.readwrite, function (transaction) {
                    var objectStore = transaction.objectStore(store);
                    data[store].forEach(function (item) {
                        return objectStore[method](item);
                    });
                });
            }, this);

            return Promise.all(promises);
        };

        IndexedDBClient.prototype.transaction = function (store, type, fn) {
            var _this2 = this;

            return new Promise(function (resolve, reject) {
                var transaction = _this2.database.transaction(store, type);
                var returnValue = fn(transaction);

                if (returnValue) {
                    returnValue.onsuccess = resolve;
                    returnValue.onerror = reject;
                } else {
                    transaction.oncomplete = resolve;
                    transaction.onerror = reject;
                }
            });
        };

        function getObjectStoreNames(database) {
            var stores = [];
            var domStringList = database.objectStoreNames;
            for (var i = 0; i < domStringList.length; i++) {
                stores.push(domStringList[i]);
            }
            return stores;
        }

        /***/
    },
    /* 8 */
    /***/ function (module, exports) {

        'use strict';

        Object.defineProperty(exports, "__esModule", {
            value: true
        });
        /**
         * promiseLogger
         *
         * @param   Object{ enabled: Boolean, title: String }
         * @param   Promise
         * @returns Promise
         *
         * Logs resolve or reject state changes on a promise. Can be dynamically
         * enabled and disabled using the enabled key in config -- it defaults to
         * disabled to prevent accidental logging in production. A title can be added to
         * each log line using the title key specified in config.
         *
         */
        function promiseLogger(config, promise) {
            config = config || {enabled: false, title: null};
            if (!config.enabled) {
                return promise;
            } else {
                var resolveLogger = logHandler(config.title, 'resolved', 'info');
                var rejectLogger = logHandler(config.title, 'rejected', 'warn');
                return promise.then(resolveLogger, function (err) {
                    throw rejectLogger(err);
                });
            }
        }

        function logHandler(title, state, level) {
            return function (value) {
                var message = ('[' + state + '] ' + (title || '')).trim();
                console[level || 'log'](message, Array.prototype.slice.call(arguments));
                return value;
            };
        }

        exports.default = promiseLogger;

        /***/
    }
    /******/]);